package cn.bonoon.kernel.events;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.springframework.context.ApplicationContext;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.support.entities.AbstractEntity;

/**
 * <pre>
 * 操作事件
 * 主要是由控制器生成，并值给业务逻辑层处理
 * 事件里可以附加更多的操作参数，这些参数可以在业务逻辑实现里重写操作方法来调用
 * </pre>
 * @author jackson
 *
 */
public final class OperateEvent extends AbstractEvent{
	
	/**
	 * 是否指示需要继续处理
	 */
	private boolean stop;
	
	private Throwable exception;
	private final long now;
	private Date date;
	private final String mid;
	/**
	 * 事务的同步锁，一般只锁住同一个用户的同一个操作，防止用户在界面双击或多击提交的按钮，造成多次操作数据库的情况
	 */
	public final Object lock;
	
	public Throwable getException() {
		return exception;
	}
	
	public String getMid() {
		return mid;
	}
	
	public HttpServletRequest getRequest() {
		return request;
	}
	
	public OperateEvent(ApplicationContext applicationContext, HttpServletRequest request, Object source, IOperator operator){
		super(applicationContext, request, source, operator);
		this.lock = operator;
		this.mid = null;
//		this.logger = logger;
		this.now = System.currentTimeMillis();
	}
	
	public OperateEvent(ApplicationContext applicationContext, String mid, HttpServletRequest request, Object source, IOperator operator){
		super(applicationContext, request, source, operator);
		this.lock = operator;
		this.mid = mid;
//		this.logger = logger;
		this.now = System.currentTimeMillis();
	}
	
	public void error(Throwable ex){
		exception = ex;
//		logger.Log(ex);
	}
	
	public boolean isStop() {
		return stop;
	}
	public Date now(){
		if(null == date) date = new Date(now);
		return date;
	}

	public void setException(RuntimeException exception) {
		this.exception = exception;
	}
	
	public MultipartFile getFile(String name){
		if(request instanceof MultipartHttpServletRequest){
			return ((MultipartHttpServletRequest) request).getFile(name);
		}
		return null;
	}
	
	public void init(AbstractEntity entity){
		entity.setCreateAt(now());
		entity.setCreatorId(getId());
		entity.setCreatorName(getUsername());
		entity.setOwnerId(getOwnerId());
	}
	
	public void update(AbstractEntity entity){
		entity.setUpdateAt(now());
		entity.setUpdaterId(getId());
		entity.setUpdaterName(getUsername());
	}
	
//	private final ILogger logger;
//	private OperateScope scope = OperateScope.DOMAIN;
	
//	public void setScope(OperateScope scope) {
//		this.scope = scope;
//	}

//	public void log(String operateName) {
//		// TODO Auto-generated method stub
//		
//	}
	
//	public OperateScope getScope() {
//		return scope;
//	}
//
//	/**
//	 * <pre>
//	 * 操作范围的限定，只有继承于AbstractEntity的实体才能使用操作范围的限定
//	 * </pre>
//	 * @author jackson
//	 *
//	 */
//	public enum OperateScope{
//		/**
//		 * 
//		 */
//		NULL,
//		/**
//		 * 域范围，即需要具有相同的ownerid的实体
//		 */
//		DOMAIN,
//		/**
//		 * 专属范围，即只有createrid与当前登录用户的id相同才允许操作
//		 */
//		EXCLUSIVE,
//		/**
//		 * 所有的操作范围
//		 */
//		GLOBAL
//	}
}
